use super::{pack_and_return_error, pack_and_return_message, pack_and_return_status_and_bytes};
use crate::{application::Application, service::service::Service};

use common::{
    base::status::Status,
    serial::request_message::RequestMessage,
    service::sys_service_api::http::{HttpRequest, HttpResponse},
};
use tracing::error;

pub extern "C" fn send_http_request(service_id: i64, request_id: i64, msg: *const u8, len: u32) {
    let slice = unsafe { std::slice::from_raw_parts(msg, len as usize) };
    let mut request = HttpRequest::default();
    request.parse_from_bytes(slice).unwrap();
    tokio::spawn(async move {
        let airport = Application::get_airport();
        let dxc_manager = airport.get_dxc_manager();
        let local_service = dxc_manager.get_local_service_by_id(service_id).await;
        if local_service.is_none() {
            error!("调用的服务已经下线!");
            return;
        }
        //
        let local_service = local_service.unwrap();

        let http_client = airport.http_net.new_client(request_id);
        let mut http_client = http_client.lock().await;
        let ret = http_client.do_request(request).await;
        //
        if ret.is_err() {
            return pack_and_return_error(
                request_id,
                local_service.get_service_key(),
                ret.err().unwrap(),
            );
        }
        //
        let mut response = HttpResponse::default();
        unsafe {
            let headers = http_client.res.assume_init_ref().headers();
            for (key, value) in headers {
                let str_value = String::from_utf8_unchecked(value.as_bytes().to_vec());
                response.headers.insert(key.to_string(), str_value);
            }
        }
        pack_and_return_message(request_id, local_service.get_service_key(), response);
        // 发送回去
    });
}

pub extern "C" fn get_http_data(service_id: i64, request_id: i64) {
    tokio::spawn(async move {
        let airport = Application::get_airport();
        let dxc_manager = airport.get_dxc_manager();
        let local_service = dxc_manager.get_local_service_by_id(service_id).await;
        if local_service.is_none() {
            error!("调用的服务已经下线!");
            return;
        }
        let local_service = local_service.unwrap();
        let http_client = airport.http_net.get_http_client(request_id);
        if http_client.is_none() {
            pack_and_return_error(
                request_id,
                local_service.get_service_key(),
                Status::error("链接不存在！".into()),
            );
            return;
        }

        let http_client = http_client.unwrap();
        let mut http_client = http_client.lock().await;
        let ret = http_client.get_data().await;
        if ret.is_err() {
            pack_and_return_error(
                request_id,
                local_service.get_service_key(),
                ret.err().unwrap(),
            );
        } else {
            pack_and_return_status_and_bytes(
                request_id,
                local_service.get_service_key(),
                Status::default(),
                ret.unwrap(),
            );
        }
    });
}

pub extern "C" fn remove_http_client(service_id: i64, request_id: i64) {
    tokio::spawn(async move {
        let airport = Application::get_airport();
        let dxc_manager = airport.get_dxc_manager();
        let local_service = dxc_manager.get_local_service_by_id(service_id).await;
        if local_service.is_none() {
            error!("调用的服务已经下线!");
            return;
        }
        airport.http_net.remove_http_client(request_id);
    });
}
